const path = require('path');
const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const rename = require('gulp-rename');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');
const del = require('delete');
const gulpif = require('gulp-if');
const cssnano = require('cssnano');
const webserver = require('gulp-webserver');
const htmlmin = require('gulp-htmlmin');
const replace = require('gulp-replace');
const px2rem = require('gulp-px2rem');
const cheerio = require('gulp-cheerio');
const { watch, series, parallel, src, dest } = require('gulp');
let config = require('./src/config.js');
let configEnv = config[process.env.NODE_ENV || 'production'];

function clean(cb) {
  del(['dist/*'], cb);
}

function js() {
  return src('src/js/**/*.js')
    .pipe(babel({
      presets: ['@babel/env'],
    }))
    .pipe(uglify())
    .pipe(rename({ extname: '.min.js' }))
    .pipe(dest('dist/js'));
}

function css() {
  return src(['src/**/*.scss', 'src/**/*.css'])
    .pipe(sass().on('error', sass.logError))
    .pipe(px2rem({
      rootValue: 10,
      unitPrecision: 3,
      replace: true
    }))
    .pipe(postcss([autoprefixer(), cssnano()]))
    .pipe(rename({ extname: '.min.css' }))
    .pipe(gulp.dest('dist'));
}

function copyPublic() {
  return src('src/public/**/*', { encoding: false })
    .pipe(dest('dist/public'));
}

function copyImg() {
  return src('src/images/**/*', { encoding: false })
    .pipe(dest('dist/images'));
}

function html() {
  return src('src/**/*.html')
    .pipe(replace(/css\/(\w+)\.css/ig, function (match, p1) {
      return `css/${p1}.min.css?t=${Date.now()}`
    }))
    .pipe(replace(/js\/(\w+)\.js/ig, function (match, p1) {
      return `js/${p1}.min.js?t=${Date.now()}`
    }))
    .pipe(cheerio(function ($) {
      $('body').prepend(`<script>window.env = ${JSON.stringify(configEnv)}</script>`);
      if (process.env.NODE_ENV == "test") {
        $('body').prepend(`<script src="./public/vconsole.min.js"></script>`);
      }
    }))
    .pipe(htmlmin({
      removeComments: true,
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeEmptyAttributes: true,
      removeScriptTypeAttributes: false,
      removeStyleLinkTypeAttributes: true,
      minifyJS: true,
      minifyCSS: true
    }))
    .pipe(gulp.dest('dist'))
}

function web() {
  return src('dist', { allowEmpty: true })
    .pipe(webserver({
      port: 9000,
      open: false,
      host: '0.0.0.0',
      livereload: {
        enable: true,
      },
      proxies: [
        {
          source: '/qhb/ita', target: 'http://192.168.148.33:8080/qhb/ita'
        }
      ]
    }));
}

exports.build = series(
  clean,
  parallel(
    css,
    js,
    copyPublic,
    copyImg,
    html
  )
)

exports.default = function () {
  series(clean, parallel(
    css,
    js,
    copyPublic,
    copyImg,
    html,
    web
  ))()

  watch('src/**/*.scss', css);
  watch('src/js/*.js', js);
  watch('src/**/*.css', css);
  watch('src/**/*.html', html);
  watch('src/images/*', copyImg);
  watch('src/public/*', copyPublic);
  watch('./src/config.js', series(function(cb) {
    delete require.cache[require.resolve('./src/config')];
    config = require('./src/config.js');
    configEnv = config[process.env.NODE_ENV || 'production'];
    cb();
  }, html));
};
